/*! 
 * \file test_uft_mocker_basic.cpp
 * \project WonderTrader
 *
 * \author Generated
 * \date 2024/03/20
 * 
 * \brief UftMocker基础功能测试
 * 
 * \details 测试UftMocker类的基础功能，包括：
 *          - UFT策略模拟器基础构造测试
 *          - 策略上下文接口测试
 *          - 数据接收接口测试
 *          - 基础交易接口测试
 *          - 持仓管理测试
 *          - 订单管理测试
 */

#include <gtest/gtest.h>
#include <memory>
#include <string>

// 包含必要的头文件
#include "../../src/WtBtCore/UftMocker.h"
#include "../../src/WtBtCore/HisDataReplayer.h"
#include "../../src/Includes/WTSDataDef.hpp"
#include "../../src/Includes/WTSVariant.hpp"

using namespace wtp;

/**
 * @class MockHisDataReplayer
 * @brief 模拟历史数据回放器类
 * 
 * @details 用于测试UftMocker的简化历史数据回放器
 */
class MockHisDataReplayer : public HisDataReplayer {
public:
    MockHisDataReplayer() : HisDataReplayer() {}
    
    // 提供基础的模拟实现
    virtual uint64_t get_real_time() override { return 20240320093000000ULL; }
    virtual uint32_t get_trading_date() override { return 20240320; }
};

/**
 * @class UftMockerBasicTest
 * @brief UftMocker基础功能测试类
 * 
 * @details 提供UftMocker的基础功能测试环境和测试用例
 */
class UftMockerBasicTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 创建模拟历史数据回放器
        replayer_ = std::make_shared<MockHisDataReplayer>();
        
        // 创建被测试对象
        mocker_ = std::make_unique<UftMocker>(replayer_.get(), "test_uft_strategy");
    }
    
    void TearDown() override {
        mocker_.reset();
        replayer_.reset();
    }
    
    /**
     * @brief 创建测试用Tick数据
     * @param code 合约代码
     * @return WTSTickData指针
     */
    WTSTickData* createTestTick(const char* code) {
        WTSTickData* tick = WTSTickData::create(code);
        tick->set_price(100.5);
        tick->set_volume(1000);
        tick->set_turnover(100500.0);
        tick->set_open_interest(5000);
        tick->set_trading_date(20240320);
        tick->set_action_date(20240320);
        tick->set_action_time(93000000);
        return tick;
    }

protected:
    std::shared_ptr<MockHisDataReplayer> replayer_;
    std::unique_ptr<UftMocker> mocker_;
};

/**
 * @brief 测试UftMocker基础构造
 * @details 验证UftMocker对象的正确创建
 */
TEST_F(UftMockerBasicTest, TestBasicConstruction) {
    EXPECT_NE(mocker_, nullptr);
    EXPECT_NE(replayer_, nullptr);
}

/**
 * @brief 测试策略上下文ID
 * @details 验证UftMocker的策略上下文ID功能
 */
TEST_F(UftMockerBasicTest, TestContextId) {
    uint32_t id = mocker_->id();
    EXPECT_GT(id, 0);  // ID应该大于0
    
    // 多次调用应该返回相同的ID
    EXPECT_EQ(mocker_->id(), id);
    EXPECT_EQ(mocker_->id(), id);
}

/**
 * @brief 测试策略名称
 * @details 验证UftMocker的策略名称管理
 */
TEST_F(UftMockerBasicTest, TestStrategyName) {
    // 测试策略名称（通过构造函数设置）
    // 注意：实际的name()方法可能在基类中定义
    uint32_t id = mocker_->id();
    EXPECT_GT(id, 0);  // 验证对象正确初始化
}

/**
 * @brief 测试时间获取功能
 * @details 验证UftMocker的时间获取接口
 */
TEST_F(UftMockerBasicTest, TestTimeAccess) {
    // 测试实时时间获取
    uint64_t real_time = mocker_->stra_get_real_time();
    EXPECT_GT(real_time, 0);
    
    // 测试交易日期获取
    uint32_t trading_date = mocker_->stra_get_date();
    EXPECT_GT(trading_date, 20000101);  // 应该是合理的日期
    EXPECT_LT(trading_date, 30000101);  // 应该是合理的日期
}

/**
 * @brief 测试持仓查询功能
 * @details 验证UftMocker的持仓查询接口
 */
TEST_F(UftMockerBasicTest, TestPositionQuery) {
    const char* test_code = "SHFE.rb2405";
    
    // 测试初始持仓（应该为0）
    double position = mocker_->stra_get_position(test_code);
    EXPECT_DOUBLE_EQ(position, 0.0);
    
    // 测试不同的持仓查询参数
    double position_valid = mocker_->stra_get_position(test_code, true);
    EXPECT_DOUBLE_EQ(position_valid, 0.0);
    
    double position_all = mocker_->stra_get_position(test_code, false);
    EXPECT_DOUBLE_EQ(position_all, 0.0);
}

/**
 * @brief 测试资金查询功能
 * @details 验证UftMocker的资金查询接口
 */
TEST_F(UftMockerBasicTest, TestFundQuery) {
    // 测试可用资金查询
    double available_fund = mocker_->stra_get_fund_data(0);
    EXPECT_GE(available_fund, 0.0);  // 资金应该非负
    
    // 测试总资金查询
    double total_fund = mocker_->stra_get_fund_data(1);
    EXPECT_GE(total_fund, 0.0);  // 资金应该非负
}

/**
 * @brief 测试订单查询功能
 * @details 验证UftMocker的订单查询接口
 */
TEST_F(UftMockerBasicTest, TestOrderQuery) {
    const char* test_code = "SHFE.rb2405";
    
    // 测试订单查询（初始应该没有订单）
    OrderMap* orders = mocker_->stra_get_orders(test_code);
    if (orders != nullptr) {
        EXPECT_EQ(orders->size(), 0);  // 初始应该没有订单
    }
}

/**
 * @brief 测试数据订阅功能
 * @details 验证UftMocker的数据订阅接口
 */
TEST_F(UftMockerBasicTest, TestDataSubscription) {
    const char* test_code = "SHFE.rb2405";
    uint32_t context_id = mocker_->id();
    
    // 测试Tick数据订阅
    EXPECT_NO_THROW(mocker_->stra_sub_ticks(test_code));
    
    // 测试委托队列订阅
    EXPECT_NO_THROW(mocker_->stra_sub_order_queues(test_code));
    
    // 测试委托明细订阅
    EXPECT_NO_THROW(mocker_->stra_sub_order_details(test_code));
    
    // 测试成交明细订阅
    EXPECT_NO_THROW(mocker_->stra_sub_transactions(test_code));
}

/**
 * @brief 测试基础交易接口
 * @details 验证UftMocker的基础交易接口
 */
TEST_F(UftMockerBasicTest, TestBasicTrading) {
    const char* test_code = "SHFE.rb2405";
    double price = 100.5;
    double qty = 1.0;
    const char* user_tag = "test_order";
    
    // 测试买入接口
    uint32_t buy_id = mocker_->stra_buy(test_code, price, qty, user_tag);
    EXPECT_GT(buy_id, 0);  // 订单ID应该大于0
    
    // 测试卖出接口
    uint32_t sell_id = mocker_->stra_sell(test_code, price, qty, user_tag);
    EXPECT_GT(sell_id, 0);  // 订单ID应该大于0
    
    // 验证订单ID不同
    EXPECT_NE(buy_id, sell_id);
}

/**
 * @brief 测试开平仓交易接口
 * @details 验证UftMocker的开平仓交易接口
 */
TEST_F(UftMockerBasicTest, TestOpenCloseTrading) {
    const char* test_code = "SHFE.rb2405";
    double price = 100.5;
    double qty = 1.0;
    const char* user_tag = "test_order";
    
    // 测试开多仓
    uint32_t long_open_id = mocker_->stra_enter_long(test_code, price, qty, user_tag);
    EXPECT_GT(long_open_id, 0);
    
    // 测试开空仓
    uint32_t short_open_id = mocker_->stra_enter_short(test_code, price, qty, user_tag);
    EXPECT_GT(short_open_id, 0);
    
    // 测试平多仓
    uint32_t long_close_id = mocker_->stra_exit_long(test_code, price, qty, user_tag);
    EXPECT_GT(long_close_id, 0);
    
    // 测试平空仓
    uint32_t short_close_id = mocker_->stra_exit_short(test_code, price, qty, user_tag);
    EXPECT_GT(short_close_id, 0);
    
    // 验证所有订单ID不同
    EXPECT_NE(long_open_id, short_open_id);
    EXPECT_NE(long_open_id, long_close_id);
    EXPECT_NE(long_open_id, short_close_id);
}

/**
 * @brief 测试撤单功能
 * @details 验证UftMocker的撤单接口
 */
TEST_F(UftMockerBasicTest, TestOrderCancellation) {
    const char* test_code = "SHFE.rb2405";
    double price = 100.5;
    double qty = 1.0;
    const char* user_tag = "test_order";
    
    // 先下一个订单
    uint32_t order_id = mocker_->stra_buy(test_code, price, qty, user_tag);
    EXPECT_GT(order_id, 0);
    
    // 测试撤单
    bool cancel_result = mocker_->stra_cancel(order_id);
    // 注意：撤单结果可能取决于订单状态，这里主要测试接口调用
    (void)cancel_result;  // 避免未使用变量警告
}

/**
 * @brief 测试日志功能
 * @details 验证UftMocker的日志输出接口
 */
TEST_F(UftMockerBasicTest, TestLogging) {
    // 测试不同级别的日志输出
    EXPECT_NO_THROW(mocker_->stra_log_info("Test info message"));
    EXPECT_NO_THROW(mocker_->stra_log_debug("Test debug message"));
    EXPECT_NO_THROW(mocker_->stra_log_error("Test error message"));
}

/**
 * @brief 测试数据回调接口
 * @details 验证UftMocker作为数据接收器的接口
 */
TEST_F(UftMockerBasicTest, TestDataCallbacks) {
    const char* test_code = "SHFE.rb2405";
    
    // 创建测试数据
    WTSTickData* tick = createTestTick(test_code);
    
    // 测试Tick数据处理
    EXPECT_NO_THROW(mocker_->handle_tick(test_code, tick));
    
    // 清理
    tick->release();
}

/**
 * @brief 测试策略回调接口
 * @details 验证UftMocker的策略回调接口
 */
TEST_F(UftMockerBasicTest, TestStrategyCallbacks) {
    const char* test_code = "SHFE.rb2405";
    
    // 创建测试数据
    WTSTickData* tick = createTestTick(test_code);
    
    // 测试策略初始化回调
    EXPECT_NO_THROW(mocker_->on_init());
    
    // 测试Tick回调
    EXPECT_NO_THROW(mocker_->on_tick(test_code, tick));
    
    // 清理
    tick->release();
}

/**
 * @brief 测试边界条件
 * @details 验证UftMocker对各种边界条件的处理
 */
TEST_F(UftMockerBasicTest, TestBoundaryConditions) {
    // 测试空字符串合约代码
    EXPECT_NO_THROW(mocker_->stra_get_position(""));
    
    // 测试空指针处理
    EXPECT_NO_THROW(mocker_->on_tick("", nullptr));
    
    // 测试极值价格和数量
    const char* test_code = "SHFE.rb2405";
    EXPECT_NO_THROW(mocker_->stra_buy(test_code, 0.0, 0.0, ""));
    EXPECT_NO_THROW(mocker_->stra_buy(test_code, DBL_MAX, DBL_MAX, ""));
}

/**
 * @brief 测试性能特性
 * @details 验证UftMocker的性能表现
 */
TEST_F(UftMockerBasicTest, TestPerformanceCharacteristics) {
    const char* test_code = "SHFE.rb2405";
    const int test_count = 1000;
    
    // 测试持仓查询性能
    auto start = std::chrono::high_resolution_clock::now();
    
    for (int i = 0; i < test_count; ++i) {
        double position = mocker_->stra_get_position(test_code);
        (void)position;  // 避免未使用变量警告
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    
    std::cout << "持仓查询性能测试: " << test_count << " 次查询耗时 " 
              << duration.count() << " 微秒" << std::endl;
    
    // 验证性能要求（每次查询应小于10微秒）
    EXPECT_LT(duration.count() / test_count, 10);
}

/**
 * @brief 测试完整的基础工作流程
 * @details 验证UftMocker的完整基础工作流程
 */
TEST_F(UftMockerBasicTest, TestCompleteBasicWorkflow) {
    const char* test_code = "SHFE.rb2405";
    
    // 1. 验证初始状态
    EXPECT_NE(mocker_, nullptr);
    EXPECT_GT(mocker_->id(), 0);
    
    // 2. 初始化策略
    EXPECT_NO_THROW(mocker_->on_init());
    
    // 3. 订阅数据
    EXPECT_NO_THROW(mocker_->stra_sub_ticks(test_code));
    
    // 4. 查询初始状态
    double initial_position = mocker_->stra_get_position(test_code);
    EXPECT_DOUBLE_EQ(initial_position, 0.0);
    
    // 5. 执行交易
    uint32_t order_id = mocker_->stra_buy(test_code, 100.5, 1.0, "test");
    EXPECT_GT(order_id, 0);
    
    // 6. 处理数据
    WTSTickData* tick = createTestTick(test_code);
    EXPECT_NO_THROW(mocker_->on_tick(test_code, tick));
    tick->release();
    
    // 7. 查询时间信息
    uint64_t real_time = mocker_->stra_get_real_time();
    uint32_t trading_date = mocker_->stra_get_date();
    EXPECT_GT(real_time, 0);
    EXPECT_GT(trading_date, 20000101);
    
    std::cout << "UftMocker基础工作流程测试完成" << std::endl;
    std::cout << "  策略ID: " << mocker_->id() << std::endl;
    std::cout << "  交易日期: " << trading_date << std::endl;
    std::cout << "  实时时间: " << real_time << std::endl;
} 